/**
 *
 */
package com.newer.config.db;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * durid数据库连接池配置
 *
 * @author 寻添俊
 * 2018年3月9日-下午2:05:52
 */
@Configuration
@MapperScan("com.newer.dao")
public class DruidConfig {

    /**
     * 日志信息打印
     */
    Logger logger = LogManager.getLogger(this.getClass());

    // 数据库连接
    @Value("${spring.datasource.url}")
    private String dbUrl;

    // 数据库用户名
    @Value("${spring.datasource.username}")
    private String username;

    // 数据库密码
    @Value("${spring.datasource.password}")
    private String password;

    // 驱动信息
    @Value("${spring.datasource.driverClassName}")
    private String driverClassName;

    // 初始化大小
    @Value("${spring.datasource.initialSize}")
    private int initialSize;

    // 最小空闲连接
    @Value("${spring.datasource.minIdle}")
    private int minIdle;

    // 最大活动连接
    @Value("${spring.datasource.maxActive}")
    private int maxActive;

    // 从池中取连接的最大等待时间，单位ms.
    @Value("${spring.datasource.maxWait}")
    private int maxWait;

    // 每30秒运行一次空闲连接回收器
    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;

    // 池中的连接空闲30分钟后被回收,默认值就是30分钟。
    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;

    // 验证连接是否可用，使用的SQL语句
    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;

    // 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
    @Value("${spring.datasource.testWhileIdle}")
    private boolean testWhileIdle;

    // 借出连接时不要测试，否则很影响性能
    @Value("${spring.datasource.testOnBorrow}")
    private boolean testOnBorrow;

    // 在return给pool时，是否提前进行validate操作
    @Value("${spring.datasource.testOnReturn}")
    private boolean testOnReturn;

    // 配置监控统计拦截的filters，去掉后监控界面sql无法统计，'wall'用于防火墙
    @Value("${spring.datasource.filters}")
    private String filters;

    // 通过connectProperties属性来打开mergeSql功能；慢SQL记录
    @Value("${spring.datasource.logSlowSql}")
    private String logSlowSql;

    /**
     * druid数据源状态监控Servlet(可不要)
     *
     * @return
     */
    @Bean
    public ServletRegistrationBean druidServlet() {
        logger.info("init Druid Servlet Configuration ");
        ServletRegistrationBean reg = new ServletRegistrationBean();
        reg.setServlet(new StatViewServlet());
        reg.addUrlMappings("/druid/*");
        reg.addInitParameter("loginUsername", username);
        reg.addInitParameter("loginPassword", password);
        reg.addInitParameter("logSlowSql", logSlowSql);
        return reg;
    }

    /**
     * druid过滤器(可不要)
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions",
                "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        filterRegistrationBean.addInitParameter("profileEnable", "true");
        return filterRegistrationBean;
    }

    /**
     * 生成数据源
     *
     * @return
     */
    @Bean
    public DataSource druidDataSource() {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(dbUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        try {
            datasource.setFilters(filters);
        } catch (SQLException e) {
            logger.error("druid configuration initialization filter", e);
        }
        return datasource;
    }

    /**
     * mybatis-plus分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");
        return page;
    }
}